package com.unlcn.ils.wms.backend.service.inspectApp.impl;

import cn.huiyunche.commons.exception.BusinessException;
import cn.huiyunche.commons.utils.HttpRequestUtil;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.unlcn.ils.wms.backend.bo.inspectAppBO.WmsOutboundDamageDispatchBO;
import com.unlcn.ils.wms.backend.enums.*;
import com.unlcn.ils.wms.backend.enums.excp.ExcpStatusEnum;
import com.unlcn.ils.wms.backend.service.inspectApp.WmsOutboundComponentMissService;
import com.unlcn.ils.wms.base.dto.TmsInspectComponentMissDTO;
import com.unlcn.ils.wms.base.dto.WmsInspectForAppDTO;
import com.unlcn.ils.wms.base.mapper.extmapper.WmsOutboundInspectExtMapper;
import com.unlcn.ils.wms.base.mapper.inbound.TmsOutboundDamageAttachMapper;
import com.unlcn.ils.wms.base.mapper.inspectApp.*;
import com.unlcn.ils.wms.base.mapper.outbound.WmsOutboundTaskMapper;
import com.unlcn.ils.wms.base.model.inbound.TmsOutboundDamageAttach;
import com.unlcn.ils.wms.base.model.inbound.TmsOutboundDamageAttachExample;
import com.unlcn.ils.wms.base.model.inspectApp.*;
import com.unlcn.ils.wms.base.model.outbound.WmsOutboundTask;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 缺件功能
 **/
@Service
public class WmsOutboundComponentMissServiceImpl implements WmsOutboundComponentMissService {

    private Logger logger = LoggerFactory.getLogger(WmsOutboundComponentMissServiceImpl.class);

    @Value("${tms.pickup.host.url}")
    private String propertyUrl;

    @Value("${tms.pickup.host.timeout}")
    private String propertyTime;

    @Value("${tms.encode.key}")
    private String propertyKey;

    private static final String OUTBOUND_NORMAL = "1", OUTBOUND_EXCP = "2";

    @Autowired
    private WmsOutboundComponentMissExpandMapper wmsOutboundComponentMissExpandMapper;

    @Autowired
    private TmsOutboundComponentMissMapper tmsOutboundComponentMissMapper;

    @Autowired
    private WmsOutboundTaskMapper wmsOutboundTaskMapper;

    @Autowired
    private TmsOutboundInspectExcpMapper tmsOutboundInspectExcpMapper;

    @Autowired
    private TmsOutboundInspectLogMapper tmsOutboundInspectLogMapper;

    @Autowired
    private TmsOutboundDamageAttachMapper tmsOutboundDamageAttachMapper;

    @Autowired
    private WmsOutboundInspectExtMapper wmsOutboundInspectExtMapper;

    @Autowired
    private TmsInspectExcpTypeMapper tmsInspectExcpTypeMapper;

    @Autowired
    private TmsOutboundExcpAttachsMapper tmsOutboundExcpAttachsMapper;


    /**
     * <p>
     * 2018-5-10 新增仓库code区分
     * </p>
     * 获取缺件列表
     */
    @Override
    public List<TmsInspectComponentMissDTO> getComponentMissList(String vin, String whCode) {
        logger.info("WmsOutboundComponentMissServiceImpl.getComponentMissList param {}", vin);
        if (StringUtils.isBlank(vin)) {
            throw new BusinessException("车架号不能为空!");
        }
        if (StringUtils.isBlank(whCode)) {
            throw new BusinessException("仓库code不能为空!");
        }
        List<TmsInspectComponentMissDTO> result = null;
        try {
            result = Lists.newArrayList();
            //查询缺件列表
            HashMap<String, Object> params = Maps.newHashMap();
            params.put("whCode", whCode);
            params.put("notDel", DeleteFlagEnum.NORMAL.getValue());
            params.put("vin", vin);
            List<TmsInspectComponentMissDTO> missComponents = wmsOutboundComponentMissExpandMapper.selectMissComponent(params);
            if (CollectionUtils.isNotEmpty(missComponents)) {
                for (TmsInspectComponentMissDTO missDTO : missComponents) {
                    TmsInspectComponentMissDTO componentMissDTO = new TmsInspectComponentMissDTO();
                    BeanUtils.copyProperties(missDTO, componentMissDTO);
                    componentMissDTO.setMissingStatus(true);
                    result.add(componentMissDTO);
                }
            }
            //查询非缺件列表
            List<TmsInspectComponentMissDTO> notMissComponent = wmsOutboundComponentMissExpandMapper.selectNotMissComponent(params);
            if (CollectionUtils.isNotEmpty(notMissComponent)) {
                for (TmsInspectComponentMissDTO componentMissDTO : notMissComponent) {
                    TmsInspectComponentMissDTO notMissDTO = new TmsInspectComponentMissDTO();
                    BeanUtils.copyProperties(componentMissDTO, notMissDTO);
                    notMissDTO.setMissingStatus(false);
                    result.add(notMissDTO);
                }
            }
            if (Objects.equals(result, null)) {
                throw new BusinessException("缺件列表暂无数据");
            }
            //按照id排序
            result.sort(Comparator.comparing(TmsInspectComponentMissDTO::getComponentId));
        } catch (Exception e) {
            logger.error("WmsOutboundComponentMissServiceImpl.getComponentMissList param {}", e);
            throw new BusinessException("查询缺件列表异常!");
        }
        return result;
    }

    /**
     * <p>
     * 2018-5-10 缺件增加仓库code区分
     * </p>
     * 保存并编辑缺件列表
     */
    @Override
    public void saveComponentMiss(WmsInspectForAppDTO dto) {
        logger.info("WmsOutboundComponentMissServiceImpl.saveComponentMiss param {}", dto);
        if (dto == null) {
            throw new BusinessException("传入参数为空!");
        }
        String missIds = dto.getMissIds();
        Long inspectId = dto.getInspectId();
        String userId = dto.getUserId();
        String whCode = dto.getWhCode();
        if (Objects.equals(inspectId, null)) {
            throw new BusinessException("出库单Id不能为空!");
        }
        if (StringUtils.isBlank(userId)) {
            throw new BusinessException("验车用户Id不能为空!");
        }
        if (StringUtils.isBlank(whCode)) {
            throw new BusinessException("仓库code不能为空!");
        }
        WmsOutboundTask outboundTask = null;
        outboundTask = wmsOutboundTaskMapper.selectByPrimaryKey(inspectId);
        if (Objects.equals(outboundTask, null)) {
            throw new BusinessException("未查询到对应的车辆信息");
        }
        if (!Objects.equals(outboundTask, null)) {
            if (Objects.equals(outboundTask.getInspectStatus(), WmsOutboundInspectStatusEnum.WAYBILL_QUALIFY.getValue())
                    || Objects.equals(outboundTask.getInspectStatus(), WmsOutboundInspectStatusEnum.WAYBILL_DAMAGE.getValue())) {
                throw new BusinessException("已发运车辆不能进行异常标记");
            }
            //先删除原来的缺件异常0---逻辑删除
            TmsOutboundComponentMissExample missExample = new TmsOutboundComponentMissExample();
            TmsOutboundComponentMissExample.Criteria criteria = missExample.createCriteria();
            criteria.andInspectIdEqualTo(outboundTask.getOtId())
                    .andIsDeletedEqualTo(DeleteFlagEnum.NORMAL.getValue());
            TmsOutboundComponentMiss miss = new TmsOutboundComponentMiss();
            miss.setGmtUpdate(new Date());
            miss.setIsDeleted(DeleteFlagEnum.DELETED.getValue());
            tmsOutboundComponentMissMapper.updateByExampleSelective(miss, missExample);
            //再插入新的异常记录
            if (StringUtils.isNotBlank(missIds)) {
                String[] ids_array = missIds.split(",");
                //将缺件数据插入关联表,标记验车单为异常
                for (String id : ids_array) {
                    //判断是否存在
                    //先删除原来的异常和图片--因维修要展示经维修并且已关闭的异常为减少判断-在进行异常标注的时候
                    // 1.先将本次要标记的异常在之前的异常记录比对，如果在以前是存在的--就将时间戳及异常类型设置为空(标记异常的时候)
                    //2.插入本次标记的异常及关联的图片
                    //3.再将原来不存在于本次标记异常类的数据并且含有时间戳的数据统一更新为当前要标注的一批的时间戳(验车登记的时候)
                    TmsOutboundComponentMissExample componentMissExample = new TmsOutboundComponentMissExample();
                    componentMissExample.createCriteria().andInspectIdEqualTo(inspectId)
                            .andComponentIdEqualTo(Long.parseLong(id))
                            .andWhCodeEqualTo(whCode)
                            .andExcpTimestampIsNotNull();
                    TmsOutboundComponentMiss componentMiss = new TmsOutboundComponentMiss();
                    componentMiss.setGmtUpdate(new Date());
                    componentMiss.setIsDeleted(DeleteFlagEnum.NORMAL.getValue());
                    componentMiss.setExcpTimestamp(null);
                    componentMiss.setExcpTypeCode(null);
                    tmsOutboundComponentMissMapper.updateByExampleSelective(componentMiss, componentMissExample);

                    TmsOutboundComponentMiss componentMissNew = new TmsOutboundComponentMiss();
                    componentMissNew.setComponentId(Long.parseLong(id));
                    componentMissNew.setInspectId(outboundTask.getOtId());
                    componentMissNew.setInspectVin(outboundTask.getOtVin());
                    componentMissNew.setIsDeleted(DeleteFlagEnum.NORMAL.getValue());
                    componentMissNew.setGmtCreate(new Date());
                    componentMissNew.setGmtUpdate(new Date());
                    componentMissNew.setWhCode(whCode);
                    tmsOutboundComponentMissMapper.insertSelective(componentMissNew);
                }
                //标记为异常
                outboundTask.setInspectStatus(WmsOutboundInspectStatusEnum.WAYBILL_EXCP.getValue());
                outboundTask.setGmtModify(new Date());
                outboundTask.setInspectTime(new Date());
                outboundTask.setModifyUserId(userId);
                wmsOutboundTaskMapper.updateByPrimaryKeySelective(outboundTask);

            } else {
                //检查是否还存在其他异常,没有就直接标记为合格
                //int del_value = DeleteFlagEnum.NOT_QUIT.getValue();
                //int excpValue = TmsInspectStatusEnum.WAYBILL_EXCP.getValue();//异常状态
                //int closedExcp = TmsInsepectExcpStatusEnum.BILL_CLOSEERROR.getValue();
                //int damageValue = TmsInspectStatusEnum.WAYBILL_DAMAGE.getValue();//带伤提车
                //int compromiseValue = TmsInspectStatusEnum.WAYBILL_COMPROMISE.getValue();//让步合格
                //int hasNotPickup = TmsPickupStatusEnum.WAYBILL_INIT.getValue();//未提车
                //int count = tmsInspectExcpExpandMapper.selectExcpListCountByInspectId(outboundTask.getId(), excpValue, damageValue, compromiseValue, hasNotPickup, del_value, closedExcp);
                TmsOutboundInspectExcpExample outboundInspectExcpExample = new TmsOutboundInspectExcpExample();
                TmsOutboundInspectExcpExample.Criteria excpExampleCriteria = outboundInspectExcpExample.createCriteria();
                excpExampleCriteria.andInspectIdEqualTo(outboundTask.getOtId());
                excpExampleCriteria.andDelFlagNotEqualTo(false);
                excpExampleCriteria.andDealStatusNotEqualTo(WmsExcpStatusEnum.CLOSED_EXCP.getValue());
                int count = tmsOutboundInspectExcpMapper.countByExample(outboundInspectExcpExample);
                if (count == 0) {
                    //没有任何异常,标记为待验车状态
                    outboundTask.setInspectStatus(WmsOutboundInspectStatusEnum.WAYBILL_INIT.getValue());
                    outboundTask.setGmtModify(new Date());
                    outboundTask.setInspectTime(new Date());
                    outboundTask.setModifyUserId(userId);
                }
                wmsOutboundTaskMapper.updateByPrimaryKeySelective(outboundTask);
            }
            WmsOutboundTask finalOutboundTask = outboundTask;
            new Thread(() -> {
                //插入日志
                TmsOutboundInspectLog log = new TmsOutboundInspectLog();
                saveLog(userId, finalOutboundTask, log);
                tmsOutboundInspectLogMapper.insertSelective(log);
            }).start();
        }
    }

    /**
     * 正常发运
     *
     */
    @Override
    public void updateDispatch(Long inspectId, String userId) {
        logger.info("WmsOutboundComponentMissServiceImpl.updateDispatch param {}", inspectId, userId);
        if (Objects.equals(inspectId, null)) {
            throw new BusinessException("出库单Id不能为空!");
        }
        if (StringUtils.isBlank(userId)) {
            throw new BusinessException("验车用户Id信息不能为空!");
        }
        //更新出库任务单的验车状态为正常发运
        WmsOutboundTask outboundTask = wmsOutboundTaskMapper.selectByPrimaryKey(inspectId);
        if (!Objects.equals(outboundTask, null)) {
            if (!outboundTask.getOtStatus().equals(String.valueOf(WmsOutboundTaskStatusEnum.WMS_OUTBOUND_TASK_STATUS_FINISHED.getValue()))) {
                throw new BusinessException("该车辆需备料完成!");
            }
            if (Objects.equals(outboundTask.getInspectStatus(), WmsOutboundInspectStatusEnum.WAYBILL_EXCP.getValue())) {
                throw new BusinessException("异常车辆,只能带伤发运");
            }
            if (Objects.equals(outboundTask.getInspectStatus(), WmsOutboundInspectStatusEnum.WAYBILL_QUALIFY.getValue())
                    || Objects.equals(outboundTask.getInspectStatus(), WmsOutboundInspectStatusEnum.WAYBILL_DAMAGE.getValue())) {
                throw new BusinessException("该车辆已经发运,无需重复操作!");
            }
            outboundTask.setInspectStatus(WmsOutboundInspectStatusEnum.WAYBILL_QUALIFY.getValue());
            outboundTask.setOtOutboundFlag(WmsOutboundTaskOutboundFlagEnum.HAS_OUTBOUND.getValue());
            //设置验车结果和结果描述
            TmsInspectStatusEnum statusEnum = TmsInspectStatusEnum.getByValue(TmsInspectStatusEnum.WAYBILL_QUALIFY.getValue());
            if (statusEnum != null) {
                outboundTask.setOtCheckResult(statusEnum.getText());
            }
            WmsCheckDescEnum descEnum = WmsCheckDescEnum.getByValue(TmsInspectStatusEnum.WAYBILL_QUALIFY.getValue());
            if (descEnum != null) {
                outboundTask.setOtCheckDesc(descEnum.getText());
            }
            outboundTask.setInspectTime(new Date());
            outboundTask.setGmtModify(new Date());
            outboundTask.setModifyUserId(userId);
            wmsOutboundTaskMapper.updateByPrimaryKeySelective(outboundTask);
            //重庆库要调用tms接口进行出库确认
            if (Objects.equals(outboundTask.getOtWhCode(), WhCodeEnum.UNLCN_XN_CQ.getValue())) {
                //调用tms出库确认接口
                String result = callTms(outboundTask.getOtVin(), outboundTask.getOtWaybillNo(), userId, outboundTask.getOtWhName(), OUTBOUND_NORMAL);
                parseResult(result);
                //插入日志
                new Thread(() -> {
                    TmsOutboundInspectLog log = new TmsOutboundInspectLog();
                    saveLog(userId, outboundTask, log);
                    tmsOutboundInspectLogMapper.insertSelective(log);
                }).start();

            }
        }
    }

    private void parseResult(String result) {
        if (StringUtils.isNotBlank(result)) {
            JSONObject jsonObject = JSONObject.parseObject(result);
            String msg = jsonObject.getString("message");
            String records = jsonObject.getString("records");
            Boolean success = jsonObject.getBoolean("success");
            if (!success) {
                throw new BusinessException("调用tms异常!");
            }
        }
    }


    /**
     * 带伤发运
     */
    @Override
    public void updateDamageDispatch(WmsOutboundDamageDispatchBO bo) {
        logger.info("WmsOutboundComponentMissServiceImpl.updateDamageDispatch param {}", bo);
        if (Objects.equals(bo.getInspectId(), null)) {
            throw new BusinessException("出库单Id不能为空!");
        }
        if (StringUtils.isBlank(bo.getUserId())) {
            throw new BusinessException("验车用户Id信息不能为空!");
        }
        if (StringUtils.isBlank(bo.getAttachs())) {
            throw new BusinessException("带伤发运图片不能为空!");
        }
        //更新出库任务单的验车状态为带伤发运
        TmsOutboundInspectLog log = new TmsOutboundInspectLog();
        WmsOutboundTask outboundTask = wmsOutboundTaskMapper.selectByPrimaryKey(bo.getInspectId());
        try {
            if (!Objects.equals(outboundTask, null)) {
                //更新任务的状态
                updateOutTaskToDamage(bo, outboundTask);
                //保存带伤发运图片信息,先删除原来的
                TmsOutboundDamageAttachExample attachExample = new TmsOutboundDamageAttachExample();
                attachExample.createCriteria().andOutboundTaskIdEqualTo(bo.getInspectId());
                tmsOutboundDamageAttachMapper.deleteByExample(attachExample);
                String[] attachs_key = bo.getAttachs().split(",");
                Arrays.stream(attachs_key).forEach(V -> {
                    TmsOutboundDamageAttach damageAttach = new TmsOutboundDamageAttach();
                    damageAttach.setGmtCreate(new Date());
                    damageAttach.setGmtUpdate(new Date());
                    damageAttach.setOutboundTaskId(bo.getInspectId());
                    damageAttach.setPicKey(V);
                    damageAttach.setVin(outboundTask.getOtVin());
                    tmsOutboundDamageAttachMapper.insertSelective(damageAttach);
                });

                //重庆库要调用tms接口进行出库确认
                if (Objects.equals(outboundTask.getOtWhCode(), WhCodeEnum.UNLCN_XN_CQ.getValue())) {
                    //调用tms出库确认接口；
                    String result = callTms(outboundTask.getOtVin(), outboundTask.getOtWaybillNo(), bo.getUserId(), outboundTask.getOtWhName(), OUTBOUND_NORMAL);
                    //解析tms返回结果
                    parseResult(result);
                    //插入日志
                    saveLog(bo.getUserId(), outboundTask, log);
                    tmsOutboundInspectLogMapper.insertSelective(log);
                }
            }
        } catch (Exception e) {
            if (!Objects.equals(outboundTask, null)) {
                saveLog(bo.getUserId(), outboundTask, log);
                log.setMsg("带伤发运失败");
                tmsOutboundInspectLogMapper.insertSelective(log);
            }
            logger.error("WmsOutboundComponentMissServiceImpl.updateDamageDispatch", e);
            throw new BusinessException("带伤发运失败" + e.getMessage());
        }

    }

    private void updateOutTaskToDamage(WmsOutboundDamageDispatchBO bo, WmsOutboundTask outboundTask) {
        if (!outboundTask.getOtStatus().equals(String.valueOf(WmsOutboundTaskStatusEnum.WMS_OUTBOUND_TASK_STATUS_FINISHED.getValue()))) {
            throw new BusinessException("该车辆需备料完成!");
        }
        if (Objects.equals(outboundTask.getInspectStatus(), WmsOutboundInspectStatusEnum.WAYBILL_INIT.getValue())) {
            throw new BusinessException("请先进行验车操作");
        }
        if (Objects.equals(outboundTask.getInspectStatus(), WmsOutboundInspectStatusEnum.WAYBILL_QUALIFY.getValue())
                || Objects.equals(outboundTask.getInspectStatus(), WmsOutboundInspectStatusEnum.WAYBILL_DAMAGE.getValue())) {
            throw new BusinessException("该车辆已经发运,无需重复操作!");
        }
        outboundTask.setInspectStatus(WmsOutboundInspectStatusEnum.WAYBILL_DAMAGE.getValue());
        outboundTask.setOtOutboundFlag(WmsOutboundTaskOutboundFlagEnum.HAS_OUTBOUND.getValue());
        outboundTask.setInspectTime(new Date());
        outboundTask.setGmtModify(new Date());
        outboundTask.setModifyUserId(bo.getUserId());
        TmsInspectStatusEnum statusEnum = TmsInspectStatusEnum.getByValue(TmsInspectStatusEnum.WAYBILL_EXCP.getValue());
        if (statusEnum != null) {
            WmsCheckResultEnum resultEnum = WmsCheckResultEnum.getByValue(statusEnum.getValue());
            if (resultEnum != null) {
                outboundTask.setOtCheckResult(resultEnum.getText());
            }
        }
        WmsCheckDescEnum descEnum = WmsCheckDescEnum.getByValue(TmsInspectStatusEnum.WAYBILL_EXCP.getValue());
        if (descEnum != null) {
            outboundTask.setOtCheckDesc(descEnum.getText());
        }

        //删除原来的所有数据并复制新增--因为维修再进行验车的作业 分批次显示
        //int count1 = 0;
        //int count2 = 0;
        //count1 = updateExcpToDelAndInsertNew(bo, count1);
        //
        //count2 = updateMissTodelAndInsertNew(bo, count2);

        //标记异常类型
        int closed_excpValue = WmsExcpStatusEnum.CLOSED_EXCP.getValue();
        int del_flag = DeleteFlagEnum.DELETED.getValue();
        int count1 = wmsOutboundInspectExtMapper.selectExcpCountByInspectId(bo.getInspectId(), closed_excpValue, del_flag);
        //统计缺件异常数量
        TmsOutboundComponentMissExample missExample = new TmsOutboundComponentMissExample();
        missExample.createCriteria().andInspectIdEqualTo(bo.getInspectId())
                .andIsDeletedNotEqualTo(DeleteFlagEnum.DELETED.getValue());
        int count2 = tmsOutboundComponentMissMapper.countByExample(missExample);

        //设置异常类型并保存维修异常的分批时间戳
        updateExcpTypeAndTimestampToOneBatch(bo, outboundTask, count1, count2);

        wmsOutboundTaskMapper.updateByPrimaryKeySelective(outboundTask);
    }

    /**
     * 维修不合格的时候-- 不支持分批次显示异常信息
     */
    private void updateExcpTypeAndTimestampToOneBatch(WmsOutboundDamageDispatchBO bo, WmsOutboundTask outboundTask, int count1, int count2) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
        String timestamp = sdf.format(new Date());
        if (count1 >= 1 && count2 >= 1) {
            //两种类型的异常  查询对应code的异常
            updateExcpType(outboundTask, WmsInspectExcpTypeEnum.TYPE_MISS_AND_EXCP.getCode());
            //设置异常类型
            //1. 更新异常明细的类型
            TmsOutboundInspectExcp inspectExcp = new TmsOutboundInspectExcp();
            inspectExcp.setExcpTypeCode(WmsInspectExcpTypeEnum.TYPE_MISS_AND_EXCP.getCode());
            inspectExcp.setGmtUpdate(new Date());
            inspectExcp.setExcpTimestamp(timestamp);
            TmsOutboundInspectExcpExample inspectExcpExample = new TmsOutboundInspectExcpExample();
            inspectExcpExample.or().andInspectIdEqualTo(bo.getInspectId())
                    .andExcpRepairIdIsNull()
                    .andDelFlagEqualTo(true);
            inspectExcpExample.or().andInspectIdEqualTo(bo.getInspectId())
                    .andDelFlagEqualTo(false)
                    .andExcpRepairIdIsNull()
                    .andExcpTimestampIsNotNull();
            tmsOutboundInspectExcpMapper.updateByExampleSelective(inspectExcp, inspectExcpExample);
            //2 更新缺件明细的类型
            TmsOutboundComponentMiss componentMiss = new TmsOutboundComponentMiss();
            componentMiss.setExcpTypeCode(WmsInspectExcpTypeEnum.TYPE_MISS_AND_EXCP.getCode());
            componentMiss.setGmtUpdate(new Date());
            componentMiss.setExcpTimestamp(timestamp);
            TmsOutboundComponentMissExample componentMissExample = new TmsOutboundComponentMissExample();
            componentMissExample.or().andInspectIdEqualTo(bo.getInspectId())
                    .andExcpRepairIdIsNull()
                    .andIsDeletedEqualTo(DeleteFlagEnum.NORMAL.getValue());
            componentMissExample.or().andInspectIdEqualTo(bo.getInspectId())
                    .andExcpRepairIdIsNull()
                    .andIsDeletedNotEqualTo(DeleteFlagEnum.DELETED.getValue())
                    .andExcpTimestampIsNotNull();
            tmsOutboundComponentMissMapper.updateByExampleSelective(componentMiss, componentMissExample);
        }
        if (count1 >= 1 && count2 < 1) {
            //一种类型的异常,非质损异常
            updateExcpType(outboundTask, WmsInspectExcpTypeEnum.TYPE_EXCP.getCode());
            //1. 更新异常明细的类型
            TmsOutboundInspectExcp inspectExcp = new TmsOutboundInspectExcp();
            inspectExcp.setExcpTypeCode(WmsInspectExcpTypeEnum.TYPE_EXCP.getCode());
            inspectExcp.setGmtUpdate(new Date());
            inspectExcp.setExcpTimestamp(timestamp);
            TmsOutboundInspectExcpExample inspectExcpExample = new TmsOutboundInspectExcpExample();
            inspectExcpExample.or().andInspectIdEqualTo(bo.getInspectId())
                    .andExcpRepairIdIsNull()
                    .andDelFlagEqualTo(true);
            inspectExcpExample.or().andInspectIdEqualTo(bo.getInspectId())
                    .andExcpRepairIdIsNull()
                    .andDelFlagEqualTo(false)
                    .andExcpTimestampIsNotNull();
            tmsOutboundInspectExcpMapper.updateByExampleSelective(inspectExcp, inspectExcpExample);
        }
        if (count1 < 1 && count2 >= 1) {
            //一种类型的异常,缺件异常
            updateExcpType(outboundTask, WmsInspectExcpTypeEnum.TYPE_MISS.getCode());
            //2 更新缺件明细的类型
            TmsOutboundComponentMiss componentMiss = new TmsOutboundComponentMiss();
            componentMiss.setExcpTypeCode(WmsInspectExcpTypeEnum.TYPE_MISS.getCode());
            componentMiss.setGmtUpdate(new Date());
            componentMiss.setExcpTimestamp(timestamp);
            TmsOutboundComponentMissExample componentMissExample = new TmsOutboundComponentMissExample();
            componentMissExample.or().andInspectIdEqualTo(bo.getInspectId())
                    .andExcpRepairIdIsNull()
                    .andIsDeletedEqualTo(DeleteFlagEnum.NORMAL.getValue());
            componentMissExample.or().andInspectIdEqualTo(bo.getInspectId())
                    .andExcpRepairIdIsNull()
                    .andIsDeletedNotEqualTo(DeleteFlagEnum.DELETED.getValue())
                    .andExcpTimestampIsNotNull();
            tmsOutboundComponentMissMapper.updateByExampleSelective(componentMiss, componentMissExample);
        }
    }

    /**
     * 维修不合格的时候-- 支持分批次显示异常信息
     */
    private void updateExcpTypeAndTimestamp(WmsOutboundDamageDispatchBO bo, WmsOutboundTask outboundTask, int count1, int count2) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
        String timestamp = sdf.format(new Date());
        if (count1 >= 1 && count2 >= 1) {
            //两种类型的异常  查询对应code的异常
            updateExcpType(outboundTask, WmsInspectExcpTypeEnum.TYPE_MISS_AND_EXCP.getCode());
            //设置异常类型
            //1. 更新异常明细的类型
            TmsOutboundInspectExcp inspectExcp = new TmsOutboundInspectExcp();
            inspectExcp.setExcpTypeCode(WmsInspectExcpTypeEnum.TYPE_MISS_AND_EXCP.getCode());
            inspectExcp.setGmtUpdate(new Date());
            inspectExcp.setExcpTimestamp(timestamp);
            TmsOutboundInspectExcpExample inspectExcpExample = new TmsOutboundInspectExcpExample();
            inspectExcpExample.createCriteria().andInspectIdEqualTo(bo.getInspectId())
                    .andDelFlagNotEqualTo(false)
                    .andExcpTimestampIsNull();
            tmsOutboundInspectExcpMapper.updateByExampleSelective(inspectExcp, inspectExcpExample);
            //2 更新缺件明细的类型
            TmsOutboundComponentMiss componentMiss = new TmsOutboundComponentMiss();
            componentMiss.setExcpTypeCode(WmsInspectExcpTypeEnum.TYPE_MISS_AND_EXCP.getCode());
            componentMiss.setGmtUpdate(new Date());
            componentMiss.setExcpTimestamp(timestamp);
            TmsOutboundComponentMissExample componentMissExample = new TmsOutboundComponentMissExample();
            componentMissExample.createCriteria().andInspectIdEqualTo(bo.getInspectId())
                    .andIsDeletedNotEqualTo(DeleteFlagEnum.DELETED.getValue())
                    .andExcpTimestampIsNull();
            tmsOutboundComponentMissMapper.updateByExampleSelective(componentMiss, componentMissExample);
        }
        if (count1 >= 1 && count2 < 1) {
            //一种类型的异常,非质损异常
            updateExcpType(outboundTask, WmsInspectExcpTypeEnum.TYPE_EXCP.getCode());
            //1. 更新异常明细的类型
            TmsOutboundInspectExcp inspectExcp = new TmsOutboundInspectExcp();
            inspectExcp.setExcpTypeCode(WmsInspectExcpTypeEnum.TYPE_EXCP.getCode());
            inspectExcp.setGmtUpdate(new Date());
            inspectExcp.setExcpTimestamp(timestamp);
            TmsOutboundInspectExcpExample inspectExcpExample = new TmsOutboundInspectExcpExample();
            inspectExcpExample.createCriteria().andInspectIdEqualTo(bo.getInspectId())
                    .andDelFlagNotEqualTo(false)
                    .andExcpTimestampIsNull();
            tmsOutboundInspectExcpMapper.updateByExampleSelective(inspectExcp, inspectExcpExample);
        }
        if (count1 < 1 && count2 >= 1) {
            //一种类型的异常,缺件异常
            updateExcpType(outboundTask, WmsInspectExcpTypeEnum.TYPE_MISS.getCode());
            //2 更新缺件明细的类型
            TmsOutboundComponentMiss componentMiss = new TmsOutboundComponentMiss();
            componentMiss.setExcpTypeCode(WmsInspectExcpTypeEnum.TYPE_MISS.getCode());
            componentMiss.setGmtUpdate(new Date());
            componentMiss.setExcpTimestamp(timestamp);
            TmsOutboundComponentMissExample componentMissExample = new TmsOutboundComponentMissExample();
            componentMissExample.createCriteria().andInspectIdEqualTo(bo.getInspectId())
                    .andIsDeletedNotEqualTo(DeleteFlagEnum.DELETED.getValue())
                    .andExcpTimestampIsNull();
            tmsOutboundComponentMissMapper.updateByExampleSelective(componentMiss, componentMissExample);
        }
    }

    private int updateMissTodelAndInsertNew(WmsOutboundDamageDispatchBO bo, int count2) {
        TmsOutboundComponentMissExample missExample = new TmsOutboundComponentMissExample();
        missExample.createCriteria().andIsDeletedNotEqualTo(DeleteFlagEnum.DELETED.getValue())
                .andInspectIdEqualTo(bo.getInspectId());
        List<TmsOutboundComponentMiss> tmsOutboundComponentMisses = tmsOutboundComponentMissMapper.selectByExample(missExample);
        if (CollectionUtils.isNotEmpty(tmsOutboundComponentMisses)) {
            count2 = tmsOutboundComponentMisses.size();
            //删除老的
            tmsOutboundComponentMisses.forEach(v -> {
                v.setGmtUpdate(new Date());
                v.setIsDeleted(DeleteFlagEnum.DELETED.getValue());
                tmsOutboundComponentMissMapper.updateByPrimaryKeySelective(v);
                //插入新的
                TmsOutboundComponentMiss miss = new TmsOutboundComponentMiss();
                BeanUtils.copyProperties(v, miss);
                miss.setGmtUpdate(new Date());
                miss.setGmtCreate(new Date());
                miss.setExcpStatus(ExcpStatusEnum.NOT_DEAL.getCode());
                miss.setIsDeleted(DeleteFlagEnum.NORMAL.getValue());
                miss.setId(null);
                miss.setExcpTimestamp(null);
                tmsOutboundComponentMissMapper.insertSelective(miss);
            });
        }
        return count2;
    }

    private int updateExcpToDelAndInsertNew(WmsOutboundDamageDispatchBO bo, int count1) {
        TmsOutboundInspectExcpExample excpExample = new TmsOutboundInspectExcpExample();
        excpExample.createCriteria().andDelFlagNotEqualTo(false)
                .andInspectIdEqualTo(bo.getInspectId());
        List<TmsOutboundInspectExcp> tmsOutboundInspectExcps = tmsOutboundInspectExcpMapper.selectByExample(excpExample);
        //删除关联的异常图片
        if (CollectionUtils.isNotEmpty(tmsOutboundInspectExcps)) {
            count1 = tmsOutboundInspectExcps.size();
            tmsOutboundInspectExcps.forEach((TmsOutboundInspectExcp v) -> {
                //删除旧的异常--逻辑
                v.setGmtUpdate(new Date());
                v.setDelFlag(false);
                tmsOutboundInspectExcpMapper.updateByPrimaryKeySelective(v);
                //插入新的
                TmsOutboundInspectExcp inspectExcp = new TmsOutboundInspectExcp();
                BeanUtils.copyProperties(v, inspectExcp);
                inspectExcp.setDelFlag(true);
                inspectExcp.setExcpStatus(ExcpStatusEnum.NOT_DEAL.getCode());
                inspectExcp.setId(null);
                inspectExcp.setGmtCreate(new Date());
                inspectExcp.setGmtUpdate(new Date());
                inspectExcp.setExcpTimestamp(null);
                tmsOutboundInspectExcpMapper.insertSelective(inspectExcp);
                TmsOutboundExcpAttachsExample attachsExample = new TmsOutboundExcpAttachsExample();
                attachsExample.createCriteria().andDelFlagNotEqualTo(false)
                        .andExcpIdEqualTo(v.getId());
                List<TmsOutboundExcpAttachs> tmsOutboundExcpAttachs = tmsOutboundExcpAttachsMapper.selectByExample(attachsExample);
                if (CollectionUtils.isNotEmpty(tmsOutboundExcpAttachs)) {
                    tmsOutboundExcpAttachs.forEach(attach -> {
                        attach.setGmtUpdate(new Date());
                        attach.setDelFlag(false);
                        tmsOutboundExcpAttachsMapper.updateByPrimaryKeySelective(attach);
                        //插入新的
                        TmsOutboundExcpAttachs excpAttachs = new TmsOutboundExcpAttachs();
                        excpAttachs.setDelFlag(true);
                        excpAttachs.setGmtCreate(new Date());
                        excpAttachs.setGmtUpdate(new Date());
                        excpAttachs.setPicKey(attach.getPicKey());
                        excpAttachs.setExcpId(inspectExcp.getId());//
                        tmsOutboundExcpAttachsMapper.insertSelective(excpAttachs);
                    });
                }
            });
        }
        return count1;
    }

    private void updateExcpType(WmsOutboundTask bill, String typeCode) {
        TmsInspectExcpTypeExample typeExample = new TmsInspectExcpTypeExample();
        typeExample.createCriteria().andDelFlagNotEqualTo(false)
                .andTypeCodeEqualTo(typeCode);
        List<TmsInspectExcpType> tmsInspectExcpTypes = tmsInspectExcpTypeMapper.selectByExample(typeExample);
        if (CollectionUtils.isNotEmpty(tmsInspectExcpTypes)) {
            //设置入库单关联对应的id
            bill.setOtExceptionType(String.valueOf(tmsInspectExcpTypes.get(0).getId()));
        }
    }


    /**
     * 调用 tms 的接口(抓取验车单信息,或者生成验车合格的状态)
     */
    private String callTms(String vin, String custshipno, String userId, String warehouse, String type) {
        // 构建URL
        String url = propertyUrl;
        Integer time = Integer.parseInt(propertyTime);
        String encode_key = propertyKey;
        Map<String, Object> map = new HashMap<>();
        Map<String, Object> headerMap = new HashMap<>();
        headerMap.put("encode-key", encode_key);
        url = url + "/mOutware.jspx";
        map.put("vin", vin);
        map.put("custshipno", custshipno);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String date_str = sdf.format(new Date());
        map.put("dt_outware", date_str);//出库时间
        map.put("userno", userId);
        map.put("warehouse", warehouse);
        map.put("type", type);
        String result = null;
        try {
            result = HttpRequestUtil.sendHttpPost(url, headerMap, map, time);
        } catch (Exception e) {
            throw new BusinessException("访问tms接口失败");
        }
        return result;
    }


    /**
     * 获取缺件列表名称
     */
    @Override
    public String getMissComponentNames(String vin, String whCode) {
        logger.info("WmsOutboundComponentMissServiceImpl.getMissComponentNames param {}", vin);
        //查询缺件列表
        HashMap<String, Object> params = Maps.newHashMap();
        params.put("whCode", whCode);
        params.put("notDel", DeleteFlagEnum.NORMAL.getValue());
        params.put("vin", vin);
        List<TmsInspectComponentMissDTO> missComponents = wmsOutboundComponentMissExpandMapper.selectMissComponent(params);
        StringBuilder sb = new StringBuilder();
        if (!Objects.equals(missComponents, null)) {
            missComponents.forEach(v -> {
                sb.append(v.getComponentName()).append(",");
            });
        }
        if (StringUtils.isNotBlank(sb)) {
            return sb.substring(0, sb.length() - 1);
        }
        return null;
    }

    /**
     * 获取缺件列表名称
     */
    @Override
    public String getMissComponentNamesNew(Long id, String whCode) {
        logger.info("WmsOutboundComponentMissServiceImpl.getMissComponentNamesNew param {}", id);
        //查询缺件列表
        HashMap<String, Object> params = Maps.newHashMap();
        params.put("inspectId",id);
        params.put("notDel",DeleteFlagEnum.NORMAL.getValue());
        params.put("whCode",whCode);
        List<TmsInspectComponentMissDTO> missComponents = wmsOutboundComponentMissExpandMapper.selectMissComponentNew(params);
        StringBuilder sb = new StringBuilder();
        if (!Objects.equals(missComponents, null)) {
            missComponents.forEach(v -> {
                sb.append(v.getComponentName()).append(",");
            });
        }
        if (StringUtils.isNotBlank(sb)) {
            return sb.substring(0, sb.length() - 1);
        }
        return null;
    }

    /**
     * 出库验车登记业务--君马
     */
    @Override
    public void updateInspectStatusById(Long inspectId, String userId, String whCode) {
        logger.info("WmsOutboundComponentMissServiceImpl.updateInspectStatusById param{},{}", inspectId, userId);
        //判断是否是异常状态
        if (Objects.equals(inspectId, null))
            throw new BusinessException("验车单id不能为空!");
        if (StringUtils.isBlank(userId))
            throw new BusinessException("用户id不能为空!");
        if (StringUtils.isBlank(whCode))
            throw new BusinessException("传入仓库code不能为空!");
        if (!(WhCodeEnum.JM_CS.getValue().equals(whCode) || WhCodeEnum.JM_XY.getValue().equals(whCode))) {
            throw new BusinessException("该仓库不能进行该操作!");
        }
        WmsOutboundTask outboundTask = wmsOutboundTaskMapper.selectByPrimaryKey(inspectId);

        if (WmsOutboundInspectStatusEnum.WAYBILL_QUALIFY.getValue() == outboundTask.getInspectStatus() ||
                WmsOutboundInspectStatusEnum.WAYBILL_DAMAGE.getValue() == outboundTask.getInspectStatus()) {
            throw new BusinessException("该车已经进行了该操作,无需重复操作!");
        }
        if (WmsOutboundInspectStatusEnum.WAYBILL_EXCP.getValue() == outboundTask.getInspectStatus()) {
            WmsOutboundDamageDispatchBO bo = new WmsOutboundDamageDispatchBO();
            bo.setInspectId(inspectId);
            bo.setUserId(userId);
            updateOutTaskToDamage(bo, outboundTask);
        }
        if (WmsOutboundInspectStatusEnum.WAYBILL_INIT.getValue() == outboundTask.getInspectStatus()) {
            updateDispatch(inspectId, userId);
        }

    }


    /**
     * 插入日志
     */
    private void saveLog(String userId, WmsOutboundTask outboundTask, TmsOutboundInspectLog log) {
        log.setMsg("更新缺件异常成功!");
        log.setGmtCreate(new Date());
        log.setGmtUpdate(new Date());
        log.setInspectId(outboundTask.getOtId());
        log.setUserId(userId);
    }

    /**
     * 统计缺件的异常数量
     */
    public Integer getMissComponentCount(String vin) {
        logger.info("WmsOutboundComponentMissServiceImpl.getMissComponentCount param {}", vin);
        if (StringUtils.isBlank(vin)) {
            throw new BusinessException("车架号不能为空!");
        }
        TmsOutboundComponentMissExample missExample = new TmsOutboundComponentMissExample();
        TmsOutboundComponentMissExample.Criteria criteria = missExample.createCriteria();
        criteria.andInspectVinEqualTo(vin);
        return tmsOutboundComponentMissMapper.countByExample(missExample);
    }
}
